package com.zhuliwei.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuliwei.constants.SystemConstants;
import com.zhuliwei.domain.ResponseResult;
import com.zhuliwei.domain.dto.MenuDto;
import com.zhuliwei.domain.entity.Menu;
import com.zhuliwei.domain.entity.RoleMenu;
import com.zhuliwei.domain.vo.MenuTreeVo;
import com.zhuliwei.mapper.MenuMapper;
import com.zhuliwei.service.MenuService;
import com.zhuliwei.service.RoleMenuService;
import com.zhuliwei.utils.SecurityUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author 朱力维
 * @since 2022-10-25 17:01:48
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    @Resource
    RoleMenuService roleMenuService;
    @Override
    public List<String> selectPermsByUserId(String id) {
        // 如果是超级管理员，返回所有的权限
        if (SecurityUtils.isSuperAdmin()) {
            LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
            lqw.in(Menu::getMenuType, SystemConstants.MENU, SystemConstants.BUTTON);
            lqw.eq(Menu::getStatus, SystemConstants.STATUS_NORMAL);
            List<Menu> menus = list(lqw);
            List<String> perms = menus.stream().map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        // 反则返回其具有的权限
        List<String> perms = getBaseMapper().selectPermsByUserId(id);
        return perms;
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(String userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是超级管理员
        if (SecurityUtils.isSuperAdmin()) {
            //如果是 返回符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        } else {
            //否则 返回当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }
        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<Menu> menuTree = builderMenuTree(menus, "0");
        return menuTree;
    }

    @Override
    public ResponseResult menuList(MenuDto menuDto) {
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        //排序
        lqw.orderByAsc(Menu::getOrderNum);
        lqw.like(StringUtils.hasText(menuDto.getMenuName()), Menu::getMenuName, menuDto.getMenuName());
        lqw.eq(StringUtils.hasText(menuDto.getStatus()), Menu::getStatus, menuDto.getStatus());
        List<Menu> list = list(lqw);
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult treeselect() {
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.orderByAsc(Menu::getOrderNum);
        List<Menu> menus = list(lqw);
        List<Menu> menuTree = builderMenuTree(menus, "0");
        return ResponseResult.okResult(menuTree);
    }

    @Override
    public ResponseResult treeselectById(String id) {
//        if (id.equals(SystemConstants.TYPE_ADMIN)){
//            throw new SystemException(AppHttpCodeEnum.ADMIN_UPDATE_ERROR);
//        }
        LambdaQueryWrapper<Menu> lqw = new LambdaQueryWrapper<>();
        lqw.orderByAsc(Menu::getOrderNum);
        List<Menu> menus = list(lqw);
        List<Menu> menuTree = builderMenuTree(menus, "0");
        LambdaQueryWrapper<RoleMenu> condition = new LambdaQueryWrapper<>();
        condition.eq(RoleMenu::getRoleId, id);
        List<RoleMenu> roleMenus = roleMenuService.list(condition);
        List<String> checkMenuIds = roleMenus.stream().map(roleMenu -> {
            return roleMenu.getMenuId();
        }).collect(Collectors.toList());
        MenuTreeVo menuTreeVo = new MenuTreeVo(menuTree, checkMenuIds);
        return ResponseResult.okResult(menuTreeVo);
    }

    private List<Menu> builderMenuTree(List<Menu> menus, String parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }

    /**
     * 获取存入参数的 子Menu集合
     *
     * @param menu
     * @param menus
     * @return
     */
    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m -> m.setChildren(getChildren(m, menus)))
                .collect(Collectors.toList());
        return childrenList;
    }

}

